package org.syncsoft.overalt.gui.api.componentPlugin;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import javax.swing.JTable;

import org.syncsoft.overalt.domain.common.entity.IEntity;
import org.syncsoft.overalt.gui.api.WindowContextValue;
import org.syncsoft.overalt.gui.api.tableDataModel.AbstractEntityTableDataModel;

/**
 * 
 * @author tptfc
 *
 */
public abstract class AbstractEntityTableComponentPlugin<T extends AbstractEntityTableDataModel<U>, U extends IEntity> extends AbstractTableDataModelComponentPlugin<T> {
	private Map<String, T> entitiesDataModel;
	
	{
		setEntitiesDataModel(new HashMap<String, T>());
	}

	protected abstract Collection<String> createCoumnsName();
	protected abstract T newEntityTableDataModel(Collection<String> columnsName, Collection<U> entities, Collection<U> selectedEntities, Collection<U> requiredEntities);
	
	/*
	 * (non-Javadoc)
	 * @see org.syncsoft.overalt.gui.swing.api.IComponentPlugin#buildContext(org.syncsoft.overalt.gui.swing.api.ContextWindowValue)
	 */
	@Override
	public void buildContext(WindowContextValue context) {
		for (String key : getEntitiesDataModel().keySet()) {
			T dataModel = getEntityDataModel(key);
			addSelectedDataInContext(key, context, dataModel);
		}
	}

	/*
	 * (non-Javadoc)
	 * @see org.syncsoft.overalt.gui.swing.api.IComponentPlugin#getContext()
	 */
	@Override
	public WindowContextValue getContext() {
		WindowContextValue context = new WindowContextValue();
		buildContext(context);
		return context;
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.syncsoft.overalt.gui.swing.api.AbstractTableDataModelComponentPlugin#getDataModelValue(int, org.syncsoft.overalt.gui.swing.api.AbstractTableDataModel)
	 */
	@Override
	protected Object getDataModelValue(int row, T dataModel) {
		return dataModel.getCode(row);
	}
	
	/**
	 * 
	 * @param entities
	 * @return
	 */
	public JTable newTable(String key, Collection<U> entities) {
		return newTable(key, entities, null);
	}

	/**
	 * 
	 * @param entities
	 * @param selectedEntities
	 * @return
	 */
	public JTable newTable(String key, Collection<U> entities, Collection<U> selectedEntities) {
		return newTable(key, entities, selectedEntities, null);
	}

	/**
	 * 
	 * @param entities
	 * @param selectedEntities
	 * @return
	 */
	public JTable newTable(String key, Collection<U> entities, Collection<U> selectedEntities, Collection<U> requiredEntities) {
		Collection<String> columnsName = createCoumnsName();
		
		JTable table;
		
		if (entities != null) {
			T dataModel = newEntityTableDataModel(columnsName, entities, selectedEntities, requiredEntities);
			table = new JTable(dataModel);
			addEntityDataModel(key, dataModel);
		} else {
			table = new JTable(null, columnsName.toArray());
		}

		table.getColumnModel().getColumn(0).setMaxWidth(30);
		
		return table;
	}
	
	/**
	 * 
	 * @param key
	 * @return
	 */
	protected T getEntityDataModel(String key) {
		T dataModel = null;
		
		if (key != null) {
			dataModel = getEntitiesDataModel().get(key);
		}
		
		return dataModel;
	}
	
	/**
	 * @precondition key and dataModel not are null
	 * @param key
	 * @param dataModel
	 */
	protected void addEntityDataModel(String key, T dataModel) {
		if (key != null && dataModel != null) {
			getEntitiesDataModel().put(key, dataModel);
		}
	}

	//	GETs AND SETs
	protected Map<String, T> getEntitiesDataModel() {
		return entitiesDataModel;
	}
	protected void setEntitiesDataModel(Map<String, T> entitiesDataModel) {
		this.entitiesDataModel = entitiesDataModel;
	}
}
